import { VercelRequest, VercelResponse } from "@vercel/node";
import "dotenv/config";
import { checkLogin } from "../../service/user/AuthService";
import { JsonWebTokenError, TokenExpiredError } from "jsonwebtoken";
import { errorWithCodeAndMsg, errorWithMsg } from "../result";
import {
  BizError,
  SysError,
  UnLoginError,
  ValidateError,
} from "../../enums/ErrorsEnum";

export type VerifyCallback = (
  request: VercelRequest,
  response: VercelResponse
) => Promise<VercelResponse>;

export type VerifyCallbackRequireLogin = (
  request: VercelRequest,
  response: VercelResponse,
  username: string
) => Promise<VercelResponse>;

/**
 * 异常处理函数
 */
export async function handleException(
  req: VercelRequest,
  rep: VercelResponse,
  runnable: VerifyCallback
): Promise<VercelResponse> {
  let result: VercelResponse;
  try {
    result = await runnable(req, rep);
  } catch (error) {
    return handleError(error, rep);
  }
  return result.status(200);
}

/**
 * 异常处理函数，并检查用户是否登录
 */
export async function handleExceptionRequireLogin(
  req: VercelRequest,
  rep: VercelResponse,
  runnable: VerifyCallbackRequireLogin
): Promise<VercelResponse> {
  let result: VercelResponse;
  let username;
  try {
    username = checkLogin(req);
  } catch (error) {
    if (error instanceof TokenExpiredError)
      return rep.status(200).json(errorWithCodeAndMsg(401, "登录信息已过期"));
    else if (error instanceof JsonWebTokenError)
      return rep.status(200).json(errorWithCodeAndMsg(401, "登录信息无效"));
    else if (error instanceof UnLoginError)
      return rep.status(200).json(errorWithCodeAndMsg(401, "请登录后再操作"));
    console.log(error)
    return rep.status(500).json(errorWithMsg("发生未知系统异常，请联系管理员"));
  }

  try {
    result = await runnable(req, rep, username);
  } catch (error) {
    return handleError(error, rep);
  }
  return result.status(200);
}

function handleError(error: any, rep: VercelResponse): VercelResponse {
  if (error instanceof ValidateError || error instanceof BizError)
    return rep.status(200).json(errorWithCodeAndMsg(400, error.message));
  else if (error instanceof SysError)
    return rep.status(500).json(errorWithMsg(error.message));
  console.log(error)
  return rep.status(500).json(errorWithMsg("发生未知系统异常，请联系管理员"));
}
